/**
 * Created by a.korotaev on 24.06.16.
 */
require('./supports');

import XLApi from './xlapi';
/**
 * Create an `Auth0` instance with `options`
 *
 * @class XL
 * @constructor
 */

const DEFAULT_CONFIG = {
    projectId: '00001',
    errorHandler: function (a) {},
    loginPassValidator: function (a, b) {
        return true;
    },
    isMarkupSocialsHandlersEnabled: false,
    apiUrl: '//login.xsolla.com/api/',
    maxXLClickDepth: 20,
    addType: 1, //添加方式 1 html方式登录 2 widget方式 3 js引入方式
    theme: 'app.default.css',
    preloader: '<div></div>',
    redirectKey: 'redirect'
};

const INVALID_LOGIN_ERROR_CODE = 1;
const INCORRECT_LOGIN_OR_PASSWORD_ERROR_CODE = 2;

class XL {
    constructor() {
        // 第三方登录地址
        this.socialUrls = {};

        // 事件
        this.eventTypes = {
            LOAD: 'load',
            CLOSE: 'close'
        };
    }

    init(options) {
        this.config = Object.assign({}, DEFAULT_CONFIG, options);
        this.api = new XLApi(options.projectId, this.config.apiUrl);

        // 是否html方式登录
        if (this.config.addType == 1) {
            this.socialUrls['sn-facebook'] = "https://www.facebook.com";
            this.socialUrls['sn-wechat'] = "https://www.wechat.com/en/";
            this.socialUrls['sn-google'] = "https://www.google.com";
            this.socialUrls['sn-linkedin'] = "https://www.linkedin.com";
            this.socialUrls['sn-aiougame'] = "http://www.aiougame.com";
            this.socialUrls['login-pass'] = "http://www.aiougame.com";

            const maxClickDepth = this.config.maxXLClickDepth;
            // Find closest ancestor with data-xl-auth attribute
            function findAncestor(el) {
                if (el.attributes['data-xl-auth']) {
                    return el;
                }
                let i = 0;
                while ((el = el.parentElement) && !el.attributes['data-xl-auth'] && ++i < maxClickDepth);
                return el;
            }

            if (this.config.isMarkupSocialsHandlersEnabled) {
                document.addEventListener('click', (e) => {
                    const target = findAncestor(e.target);
                    // Do nothing if click was outside of elements with data-xl-auth
                    if (!target) {
                        return;
                    }
                    const xlData = target.attributes['data-xl-auth'];
                    if (xlData) {
                        let nodeValue = xlData.nodeValue;
                        if (nodeValue) {
                            this.login({
                                authType: nodeValue
                            }, function (data) {
                                console.log(data);
                            });
                        }
                    }
                });
            }
        }
    }

    /**
     * Performs login
     * @param prop
     * @param error - call in case error
     * @param success
     */
    login(prop, error, success) {

        if (!prop || !this.socialUrls) {
            return;
        }

        /**
         * props
         * authType: sn-<social name>, login-pass, sms
         */
        if (prop.authType) {
            // web 跳转第三方登录
            if (prop.authType.startsWith('sn-')) {
                const socialUrl = this.socialUrls[prop.authType];
                if (socialUrl != undefined) {
                    window.location.href = this.socialUrls[prop.authType] + "?" + this.config.redirectKey + "=" + this.config.redirectUrl;
                } else {
                    console.error('Auth type: ' + prop.authType + ' doesn\'t exist');
                }
            } else if (prop.authType == 'login-pass') { // 用户名密码登录
                this.api.passlogin(prop.login, prop.pass, prop.rememberMe, this.config.redirectUrl, (res) => {
                    if (res.login_url) {
                        const finishAuth = function () {
                            window.location.href = res.login_url;
                        };
                        if (success) {
                            success({
                                status: 'success',
                                finish: finishAuth,
                                redirectUrl: res.login_url
                            });
                        } else {
                            finishAuth();
                        }
                    } else {
                        error(this.createErrorObject('Login or pass not valid', INCORRECT_LOGIN_OR_PASSWORD_ERROR_CODE));
                    }
                }, function (err) {
                    error(err);
                });
            } else if (prop.authType == 'sms') { // TODO 短信登录
                if (smsAuthStep == 'phone') {
                    this.api.smsLogin(prop.phoneNumber, null, null);
                } else if (smsAuthStep == 'code') {

                }
            } else {
                // 第三方登录方式
                switch (prop.authType) {
                    case "wechat":
                        this.api.wechatLogin(this.config.projectId, (res) => {
                            if (success) {
                                success(res);
                            } else {
                                error(this.createErrorObject('wechat login error', INCORRECT_LOGIN_OR_PASSWORD_ERROR_CODE));
                            }
                        }, function (err) {
                            error(err);
                        });
                        break;
                    case "4399":
                        this.api.r4399Login(this.config.projectId, this.getParameterByName("gameId"), this.getParameterByName("userId"), this.getParameterByName("userName"), this.getParameterByName("time"), (window.H5API ? window.H5API.getUserAvatar(this.userId) : ""), this.getParameterByName("sign"), (res) => {
                            if (success) {
                                success(res);
                            } else {
                                error(this.createErrorObject('4399 login error', INCORRECT_LOGIN_OR_PASSWORD_ERROR_CODE));
                            }
                        }, function (err) {
                            error(err);
                        });
                        break;
                    case "huawei":
                        if (egret.ExternalInterface) {
                            // 调用登录界面
                            egret.ExternalInterface.call("mobileLoginStart", "");

                            // 监听登录返回
                            egret.ExternalInterface.addCallback("mobileLogin", function (data) {
                                // console.log(data);
                                var userJson = JSON.parse(data);

                                this.api.huaweiMobileLogin(this.config.projectId, encodeURIComponent(userJson.nickName), encodeURIComponent(userJson.openId), encodeURIComponent(userJson.level), encodeURIComponent(userJson.ts), encodeURIComponent(userJson.sign), (res) => {
                                    if (success) {
                                        success(res);
                                    } else {
                                        error(this.createErrorObject('4399 login error', INCORRECT_LOGIN_OR_PASSWORD_ERROR_CODE));
                                    }
                                }, function (err) {
                                    error(err);
                                });
                            });
                        } else {
                            console.error("login", "huawei or egret js is not included.");
                        }
                        break;
                    default:
                        console.error('Unknown auth type');
                        break;
                }
            }
        }
    }

    /**
     * 支付
     * @param prop
     * @param error - call in case error
     * @param success
     */
    pay(prop, error, success) {
        // 第三方登录方式
        switch (prop.authType) {
            case "wechat":
                break;
            case "4399":
                if (window.H5API) {
                    window.H5API.openPay(params.price, params.orderInfo, params.server, null);
                } else {
                    console.error("pay", "4399 js is not included.");
                }
                break;
            case "huawei":
                var data = params.orderInfo;
                if (egret.ExternalInterface) {
                    // 调用支付界面
                    egret.ExternalInterface.call("pay", JSON.stringify(data));
                } else {
                    console.error("pay", "huawei or egret js is not included.");
                }
                break;
            default:
                console.error('Unknown auth type');
                break;
        }
    };

    /**
     * 数据上传
     * @param prop
     * @param error - call in case error
     * @param success
     */
    upload(prop, error, success) {
        // 第三方登录方式
        switch (prop.authType) {
            case "wechat":
                break;
            case "4399":
                break;
            case "huawei":
                // 类型参数type： 3 成功登陆后上传角色信息
                // 如果是type=3，需附加参数，serverId 服务器id level 等级 roleName 游戏玩家名称 roleId 角色id
                if (egret.ExternalInterface) {
                    // 调用支付界面
                    egret.ExternalInterface.call("upload", JSON.stringify(data));
                } else {
                    console.error("upload", "egret js is not included.");
                }
                break;
            default:
                console.error('Unknown auth type');
                break;
        }
    };

    createErrorObject(message, code) {
        return {
            error: {
                message: message,
                code: code || -1
            }
        };
    };

    getProjectId() {
        return this.config.projectId;
    };

    getRedirectURL() {
        return this.config.redirectUrl;
    };

    getTheme() {
        return this.config.theme;
    }

    getLoginUrl() {
        return this.config.loginUrl;
    };

    AuthWidget(elementId, options) {
        this.dispatcher = document.createElement('div');

        Object.keys(this.eventTypes).map((eventKey) => {
            this.on(this.eventTypes[eventKey]);
        });

        if (this.api) {
            if (!elementId) {
                console.error('No div name!');
            } else {
                if (options == undefined) {
                    options = {};
                }
                const width = `${options.width || 400}px`;
                const height = `${options.height || 550}px`;

                const widgetBaseUrl = options.widgetBaseUrl || 'http://www.baidu.com/';

                let src = widgetBaseUrl + options.route + '?projectId=' + this.getProjectId();

                if (this.config.locale) {
                    src = src + '&locale=' + this.config.locale;
                }
                if (this.config.fields) {
                    src = src + '&fields=' + this.config.fields;
                }
                const redirectUrl = this.getRedirectURL();
                if (redirectUrl) {
                    src = src + '&redirectUrl=' + encodeURIComponent(redirectUrl);
                }

                const loginUrl = this.getLoginUrl();
                if (loginUrl) {
                    src = src + '&login_url=' + encodeURIComponent(loginUrl);
                }

                const theme = this.getTheme();
                if (theme) {
                    src = src + '&theme=' + encodeURIComponent(theme);
                }

                const widgetIframe = document.createElement('iframe');
                widgetIframe.onload = () => {
                    element.removeChild(preloader);
                    widgetIframe.style.width = '100%';
                    widgetIframe.style.height = '100%';
                    let event = new CustomEvent('load');
                    this.dispatcher.dispatchEvent(event);
                };
                widgetIframe.style.width = 0;
                widgetIframe.style.height = 0;
                widgetIframe.frameBorder = '0';
                widgetIframe.src = src;
                widgetIframe.id = 'XsollaLoginWidgetIframe';

                const eventMethod = window.addEventListener ? 'addEventListener' : 'attachEvent';
                const eventer = window[eventMethod];
                const messageEvent = eventMethod == 'attachEvent' ? 'onmessage' : 'message';

                // Listen to message from child window
                eventer(messageEvent, (e) => {
                    let event = new CustomEvent(this.eventTypes[e.data]);
                    this.dispatcher.dispatchEvent(event);
                }, false);

                const preloader = document.createElement('div');

                preloader.innerHTML = this.config.preloader;

                const element = document.getElementById(elementId);
                if (element) {
                    element.style.width = width;
                    element.style.height = height;
                    element.appendChild(preloader);
                    element.appendChild(widgetIframe);
                } else {
                    console.error('Element \"' + elementId + '\" not found!');
                }

            }
        } else {
            console.error('Please run XL.init() first');
        }
    };

    onCloseEvent() {
        var element = document.getElementById('XsollaLoginWidgetIframe');
        element.parentNode.removeChild(element);
    }

    /**
     * link event with handler
     * @param event
     * @param handler
     */
    on(event, handler) {
        handler = handler || null;

        if (event === this.eventTypes.CLOSE) {
            if (!handler) {
                handler = this.onCloseEvent;
            } else {
                this.dispatcher.removeEventListener(event, this.onCloseEvent);
            }
        }

        this.dispatcher.addEventListener(event, handler);
    };

    /**
     * querystring 查询
     * @param name
     */
    getParameterByName(name) {
        return decodeURIComponent((document.location.search.match(new RegExp("(?:^\\?|&)" + name + "=(.*?)(?=&|$)")) || ['', ''])[1]);
    };
}

const result = new XL();

module.exports = result;